#include "shmipc/com/internal/uds_com.h"

#include <cstring>
#include <errno.h>

#include "shmipc/core/uds_socket.h"


namespace shmipc::com::internal {
using namespace shmipc::core;

XResult<XMessageSp> UdsRecvMsg(XComId com_id, int32_t timeout_ms /*= core::WaitType::WaitForever*/) {
    uint8_t hdr_data[XMSG_BASE_HDR_SIZE];
    //printf("[%s.%d]====>:\n", __FUNCTION__, __LINE__);    
    auto ret = UdsSocketRecv(com_id, (uint8_t*)&hdr_data, XMSG_BASE_HDR_SIZE, timeout_ms); //wait 10 ms,if nothing received

    //printf("[%s.%d]====>: ret: %d \n", __FUNCTION__, __LINE__, ret);
    if (!ret) { return XResult<XMessageSp>::FromError(ret.error()); }
    if (ret.value() < XMSG_BASE_HDR_SIZE) { return XResult<XMessageSp>::FromError(XErrC::Undefined); }

    uint32_t length = XMessageHelper::MsgHdrGetLength(hdr_data);

    //printf("[%s.%d]====>:msg hdr: length: %d, start_code: 0x%02x, type: %d, protocol_version: %d\n", __FUNCTION__, __LINE__, 
    //hdr.length, hdr.start_code, hdr.type, hdr.protocol_version);
    if (XMessageHelper::CheckMessageHeader(hdr_data, length)) {
        //printf("[%s.%d]====>:\n", __FUNCTION__, __LINE__);
        XMessageSp msg_ptr = XMessage::CreateMsg(hdr_data, XMSG_BASE_HDR_SIZE);
        //printf("[%s.%d]====>:\n", __FUNCTION__, __LINE__);
        if (msg_ptr) {
            uint32_t read_size = length - XMSG_BASE_HDR_SIZE;
            //printf("[%s.%d]====>:, length: %d, hdr_size:%d\n", __FUNCTION__, __LINE__, hdr.length, sizeof(hdr));
            ret = UdsSocketRecv(com_id, msg_ptr->data() + XMSG_BASE_HDR_SIZE, read_size, timeout_ms);//wait 40 ms,if nothing received
            //printf("[%s.%d]====>: ret: %d, payload_size(%d)\n", __FUNCTION__, __LINE__, ret, msg_ptr->payload_size());
            if (!ret) { return XResult<XMessageSp>::FromError(ret.error()); }

            if (ret.value() < read_size) {
                return XResult<XMessageSp>::FromError(XErrC::Undefined);
            }

            msg_ptr->set_msg_src(com_id);
            return XResult<XMessageSp>{msg_ptr};
        } else {
            //todo process this error?
            //printf("[%s.%d]====>:\n", __FUNCTION__, __LINE__);
        }
    } else {
        //todo process this error?
        return XResult<XMessageSp>::FromError(XErrC::InvalidMessage);
    }   

    //printf("[%s.%d]====>:\n", __FUNCTION__, __LINE__);
    return XResult<XMessageSp>::FromError(XErrC::Undefined);
}

} //namespace shmipc::com::internal